package com.hk.core.data.mongodb.repository;

import com.hk.commons.query.Order;
import com.hk.commons.query.QueryModel;
import com.hk.commons.query.SortUtils;
import com.hk.commons.query.page.QueryPage;
import com.hk.commons.query.page.SimpleQueryPage;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Persistable;
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.repository.NoRepositoryBean;

import java.io.Serializable;
import java.util.List;

/**
 * @author Kevin
 */
@NoRepositoryBean
public interface BaseMongoRepository<T extends Persistable<ID>, ID extends Serializable>
        extends MongoRepository<T, ID> {

    default <S extends T> QueryPage<S> queryForPage(QueryModel<S> query) {
        return queryForPage(Example.of(query.getParam()), PageRequest.of(query.getStartRowIndex(),
                query.getPageSize(), SortUtils.toSort(query.getOrders())));
    }

    default <S extends T> List<S> findAll(Example<S> example, Order... orders) {
        return findAll(example, SortUtils.toSort(orders));
    }

    default <S extends T> QueryPage<S> queryForPage(Example<S> example, Pageable pageable) {
        var page = findAll(example, pageable);
        return new SimpleQueryPage<>(page.getContent(), page.getTotalElements(),
                page.getNumber() + 1, page.getSize());
    }

    default <S extends T> QueryPage<S> queryForPage(Example<S> example, List<Order> orders,
                                                    int pageIndex, int pageSize) {
        return queryForPage(example, PageRequest.of(pageIndex, pageSize, SortUtils.toSort(orders)));
    }
}
